【PHP】インターフェース(interface / implements) - クラスに実装するメソッドの定義

【PHP】インターフェース(interface / implements) - クラスに実装するメソッドの定義

PHPにはインターフェースと呼ぶ仕組みがあります。

インターフェースはクラスで実装する必要があるメソッドを定義します。

ここでは、インターフェースについて解説します。

検証環境

インターフェース

インターフェースは“クラスに定義するメソッドを定義したモノ”です。

クラスにインターフェースを適用することを『インターフェースの実装』と呼び、その適用したクラスはインターフェースに定義したメソッドを必ず実装する必要があります。

※ 抽象クラスに適用した場合は、メソッドの実装は必須ではありません。

一般的にプログラム設計などでクラスの振る舞いを明確にするために使用し、プログラム間の窓口の役割を担います。

メリットやデメリットを理解しようとすると設計やオブジェクト指向の知識が必要になりますので、ここではプログラミングにおける使い方について解説します。

インターフェースの定義

インターフェースを使うには、定義が必要です。

基本構文

interface インターフェース名 {
    アクセス修飾子 function メソッド名( 仮引数1, 仮引数2 ... );
}

interfaceに続いてインターフェース名を記述します。

構文的にはクラスや抽象メソッドに似ていますが、インターフェースは抽象メソッドのみ定義できます。

そのため、メソッドの先頭にabstractを付ける必要がなく、メソッドは自動的に抽象メソッドとして認識されます。

サンプル

<?php

// コミュニケーションインターフェース
___ih_hl_start
interface Communication {
    
    public function greeting();
    
}
___ih_hl_end

?>
$ php sample.php
$ 

4〜8行目がインターフェースの定義です。

Communicationインターフェースを実装したクラスはgreeting抽象メソッドをオーバーライドして実装する必要があります。

インターフェースの実装

インターフェースはクラスに適用して使用します。

基本構文

class クラス名 implements インターフェース名1, インターフェース名2 ... {
    // 抽象メソッドの実装
}

クラス定義でクラス名の後にimplements インターフェース名を記述します。

インターフェースを適用したクラスは抽象メソッドの実装が必須です。

また、1つのクラスに複数のインターフェースを実装するにはカンマ(,)区切りで記述します。

サンプル

<?php

// コミュニケーションインターフェース
interface Communication {
    
    public function greeting();
    
}

// 人間クラス
___ih_hl_start
class Person implements Communication {
___ih_hl_end
    
    // 名前
    public $name;
    
    // コンストラクタ
    public function __construct( $name ) {
        $this->name = $name;
    }
    
    // あいさつ
    ___ih_hl_start
    public function greeting() {
        echo "Hello.\n";
        echo "My name is " . $this->name . "\n";
    }
    ___ih_hl_end
    
}

$person = new Person('TANAKA');
$person->greeting();

?>
$ php sample.php
Hello.
My name is TANAKA

11行目がPersonクラスへのCommunicationインターフェースの実装です。

Communicationインターフェースはgreeting抽象メソッドを持つため、22〜25行目でオーバーライドして具体的な処理を定義しています。

複数のインターフェース

複数のインターフェースを実装するサンプルを以下に示します。

<?php

// コミュニケーションインターフェース
interface Communication {
    
    public function greeting();
    
}

// 算術インターフェース
___ih_diff_start
+interface Calculation {
+    
+    public function addition( $x, $y );
+    
+}
___ih_diff_start

// 人間クラス
___ih_diff_start
-class Person implements Communication {
+class Person implements Communication, Calculation {
___ih_diff_end
    
    // 名前
    public $name;
    
    // コンストラクタ
    public function __construct( $name ) {
        $this->name = $name;
    }
    
    // あいさつ
    public function greeting() {
        echo "Hello.\n";
        echo "My name is " . $this->name . "\n";
    }
    
    ___ih_diff_start
    // 加算
+    public function addition( $x, $y ) {
+        $total = $x + $y;
+        echo $x." + ".$y." = ".$total."\n";
+    }
    ___ih_diff_end
}

$person = new Person('TANAKA');
$person->greeting();
___ih_diff_start
+$person->addition(3,8);
___ih_diff_end

?>
$ php sample.php
Hello.
My name is TANAKA
3 + 8 = 11

1つ前のサンプルにCalculationインターフェースを追加し、Personクラスで実装しました。

実装に伴ってaddition抽象メソッドをオーバーライドしています。

このようにインターフェースを複数実装する場合は、18行目のようにインターフェースをカンマ区切りで記述します。

演習問題

問題1

次の実行結果になるプログラムを作成してください。
なお、下記条件を満たすものとします。

  • 下記表のクラス・インターフェースを作成する
  • 実行結果になるように各クラスのインスタンスを使う
種類 名前 英記 継承元 インターフェース フィールド メソッド
インターフェース チケット情報 TicketInfo info()
抽象クラス チケットクラス
Ticket TicketInfo $price(料金)
具象クラス ライブチケット LiveTicket Ticket $place(場所) info()
→ 場所と料金を出力
具象クラス ライブ配信チケット LiveStreamingTicket Ticket $url(URL) info()
→ URLと料金を出力
===== ライブチケット =====
料金 : 8000円
場所 : ライブハウス
===== ライブ配信   =====
料金 : 3000円
URL : https://it-hack.net/live-streaming

問題2

次の実行結果になるプログラムを作成してください。
なお、下記条件を満たすものとします。

  • 下記表のクラス・インターフェースを作成する
  • 実行結果になるように各クラスのインスタンスを使う
種類 名前 英記 継承元 インターフェース フィールド メソッド
インターフェース 車機能 CarMethod ・display_distance()
・run_distance()
・run()
抽象クラス 車クラス
Car なし CarMethod $distance(移動距離)
※ 初期値は0
$acceleration(加速度)
※ 初期値は60
display_distance()
→ $distanceの値を出力
run()
→ run_distance()で前進距離を取得し出力する。また、$distanceに前進距離を加算
具象クラス スポーツカークラス SportCar Car なし run_distance()
→ 前進距離を計算
→ 計算式は$acceleration * 1.2
具象クラス ファミリーカークラス FamilyCar Car なし run_distance()
→ 前進距離を計算
→ 計算式は$acceleration * 0.8
===== スポーツカー  =====
72km進みます。
72km進みます。
移動距離 : 144km
===== ファミリーカー =====
48km進みます。
48km進みます。
移動距離 : 96km